/*
 * Copyright (C) 2018 The Asiainfo-Ability Authors
 *
 *      Licensed under the Apache License, Version 2.0 (the "License");
 *      you may not use this file except in compliance with the License.
 *      You may obtain a copy of the License at
 *
 *          http://www.apache.org/licenses/LICENSE-2.0
 *
 *      Unless required by applicable law or agreed to in writing, software
 *      distributed under the License is distributed on an "AS IS" BASIS,
 *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *      See the License for the specific language governing permissions and
 *      limitations under the License.
 */

package org.asiainfo.ability.manager.controler;



import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.asiainfo.ability.base.code.BizCode;
import org.asiainfo.ability.base.code.SystemCode;
import org.asiainfo.ability.base.utils.JsonUtils;
import org.asiainfo.ability.base.utils.Response;
import org.asiainfo.ability.base.utils.SeqUtils;
import org.asiainfo.ability.base.utils.Sequence;
import org.asiainfo.ability.gateway.cache.CacheService;
import org.asiainfo.ability.base.code.Constants;
import org.asiainfo.ability.gateway.code.OnOffState;
import org.asiainfo.ability.gateway.dao.ClientDao;
import org.asiainfo.ability.gateway.model.User;
import org.asiainfo.ability.gateway.vo.Token;
import org.asiainfo.ability.gateway.vo.TokenResp;
import org.asiainfo.ability.manager.service.AdminService;
import org.asiainfo.ability.manager.utils.SHAxxx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: visen
 * @Date: 2018/1/28
 * @Description:
 */
@RestController
public class ClientControler extends BaseControler {

    private Sequence seqUtils;

    @Autowired
    private ClientDao clientDao;

    @Autowired
    private CacheService cacheService;

    @Autowired
    private AdminService adminService;

    @PostConstruct
    public void init(){
        this.seqUtils = SeqUtils.newInstance();
    }
    @RequestMapping(value = "/admin/key/{type}", method = RequestMethod.POST)
    public @ResponseBody
    String getKey(@PathVariable String type, HttpServletRequest request, HttpServletResponse response) {
        if("clientId".equals(type)) {
            return SeqUtils.tokens(16);
        } else if("appSecret".equals(type)) {
            return SeqUtils.tokens(32);
        }
        return null;
    }


    @RequestMapping(value = "/admin/user", method = RequestMethod.POST)
    public @ResponseBody
    String createUser(@RequestBody User user, HttpServletRequest request
            , HttpServletResponse response) {
        try {
            user.setId(String.valueOf(seqUtils.id()));
            clientDao.saveUser(user);
        } catch (Exception e) {
            logger.error("", e);
            return Response.error("0", null);
        }
        return Response.success();
    }

    @RequestMapping(value = "/admin/user/{id}", method = RequestMethod.PUT)
    public @ResponseBody
    String updateUser(@RequestBody User user, HttpServletRequest request
            , HttpServletResponse response) {
        try {
            clientDao.updateUser(user);
            adminService.remove(CacheService.CACHE_USER, user.getId());
        } catch (Exception e) {
            logger.error("", e);
            return Response.error("0", null);
        }
        return Response.success();
    }

    @RequestMapping(value = "/admin/user/{id}", method = RequestMethod.DELETE)
    public @ResponseBody
    String deleteUser(@PathVariable String id, HttpServletRequest request
            , HttpServletResponse response) {
        try {
            clientDao.deleteUser(Long.parseLong(id));
            adminService.remove(CacheService.CACHE_USER, id);
        } catch (Exception e) {
            logger.error("", e);
            return Response.error("0", null);
        }
        return Response.success();
    }

    @RequestMapping(value = "/admin/user", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
    public @ResponseBody
    String listUsers(HttpServletRequest request
            , HttpServletResponse response) {
        try {
            List<User> users = clientDao.listUsers();
            Map ret = new HashMap<>();
            ret.put("data", users);
            ret.put("code", 0);
            ret.put("msg", "");
            ret.put("count", users.size());
            return JsonUtils.toJSON(ret);
        } catch (Exception e) {
            logger.error("", e);
            return Response.error("0", null);
        }
    }

    @RequestMapping(value = "/admin/user/{id}", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
    public @ResponseBody
    String loadUser(@PathVariable String id, HttpServletRequest request
            , HttpServletResponse response) {
        try {
            User user = clientDao.loadUser(Long.parseLong(id));
            return JsonUtils.toJSON(user);
        } catch (Exception e) {
            logger.error("", e);
            return Response.error("0", null);
        }
    }


    @RequestMapping(value = "/token", method = RequestMethod.GET)
    public @ResponseBody
    String acceptToken(HttpServletRequest request, HttpServletResponse response) {
        String clientId = request.getParameter("clientId");
        String cipher = request.getParameter("cipher");
        String timestamp = request.getParameter("timestamp");
        if (StringUtils.isBlank(clientId)
                || StringUtils.isBlank(cipher)
                || StringUtils.isBlank(timestamp)) {
            response.setStatus(HttpStatus.SC_BAD_REQUEST);
            return Response.error(SystemCode.invalid_parameter);
        }
        User user = clientDao.getUserByClientId(clientId);
        if (user == null || user.getState() == OnOffState.off) {
            response.setStatus(HttpStatus.SC_BAD_REQUEST);
            return Response.error(SystemCode.invalid_client);
        }
        if (!cipher.equals(SHAxxx.getSHA256(clientId + user.getSecretKey() + timestamp))) {

            return Response.error(BizCode.failure);
        }
        //simple implement
        Token token = new Token();
        token.setValue(UUID.randomUUID().toString().replaceAll("-", "")
                .toUpperCase());
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY, 12);
        token.setExpireTime(calendar.getTime());
        //AbilityApplicationContext.putToken(clientId, token);
        TokenResp resp = new TokenResp();
        resp.setToken(token.getValue());
        resp.setExpireTime(new SimpleDateFormat(Constants.TIMESTAMPPATTERN)
                .format(token.getExpireTime()));
        return JsonUtils.toJSON(resp);
    }

}
